﻿using System;
using System.Runtime.InteropServices;

namespace eslib.nnp5
{
    /// <summary>
    /// c++ struct结构数据包定义
    /// 
    /// T必需为struct，如:
    /// 
    /// //顺序式,1字节对齐，这里要和C++定义一致
    /// [StructLayout(LayoutKind.Sequential, Pack = 1)]
    /// public struct STest
    /// {
    ///    public int num;
    ///    //8字节数组
    ///    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
    ///    public byte[] buf;
    /// }
    /// 
    /// </summary>
    /// <typeparam name="T">必需为struct,必需指定为LayoutKind.Sequential</typeparam>
    public class StructPkg<T> : IPackage where T : struct
    {
        /// <summary>
        /// 创建新数据包
        /// </summary>
        /// <param name="obj">传递对象</param>
        /// <returns></returns>
        public static StructPkg<T> CreateNew(T obj)
        {
            StructPkg<T> spkg = new StructPkg<T>();
            spkg.Obj = obj;
            spkg.PkgData = StructConvert.StructToBytes(obj);

            return spkg;
        }


        /// <summary>
        /// 以缓存转换包，错误时抛出异常
        /// </summary>
        /// <param name="buffer">数据包</param>
        /// <returns></returns>
        public static StructPkg<T> Transfer(byte[] buffer)
        {
            StructPkg<T> spkg = new StructPkg<T>();
            spkg.PkgData = buffer;
            spkg.Obj = (T)StructConvert.BytesToStruct(buffer, typeof(T));
            return spkg;
        }



        protected StructPkg()
        {
        }


        /// <summary>
        /// 包数据
        /// </summary>
        public byte[] PkgData { get; private set; }


        /// <summary>
        /// 包对象
        /// </summary>
        public T Obj { get; private set; }


        public byte[] GetBuffer()
        {
            return PkgData;
        }
    }

}
